import {
  Card,
  Breadcrumb,
  Form,
  Button,
  Radio,
  Input,
  Upload,
  Space,
  message,
} from 'antd'
import { PlusOutlined } from '@ant-design/icons'
import { Link, useNavigate, useParams } from 'react-router-dom'
import styles from './index.module.scss'
// 导入富文本编辑器组件和样式
import ReactQuill from 'react-quill'
import 'react-quill/dist/quill.snow.css'
import Channel from '@/components/channel'
import { useEffect, useRef, useState } from 'react'
import { useDispatch } from 'react-redux'
import { publishArticleAction } from '@/store/modules/article'
import { getArticleApi } from '@/api/article'

const Publish = () => {
  const dispatch = useDispatch()
  const nav = useNavigate()
  // 获取Form组件实例
  const [form] = Form.useForm()
  // 获取文章ID
  const params = useParams()
  const articleId = params['*']
  // 是否是修改文章：true 修改 | false 发布 =》文章
  const isEdit = !!articleId
  console.log('当前修改文章ID：', articleId, isEdit)
  // 1. 已上传图片列表=> 格式：[{url:''},... ]
  const [fileList, setFileList] = useState([])
  // 备份已上传图片列表=> 切换已上传图片列表的时候，可以使用备份还原
  const backupFileList = useRef([])
  // 2. 控制上传图片的数量：上传1张或3张或0
  const [maxCount, setMacCount] = useState(1)
  /**
   * 点击加号上传图片或删除已上传图片
   * @param {*} {file:当前上传图片file对象, fileList:最新上传图片的列表}
   */
  const onUploadChange = ({ file, fileList }) => {
    console.log('上传图片或删除已上传图片:', file, fileList)
    const _fileList = fileList.map((item) => {
      // 1. 处理正在上传的图片
      if (item.response) {
        return {
          url: item.response.data.url,
        }
      }
      // 2. 已经上传图片(删除)
      return item
    })
    // 备份数据
    backupFileList.current = _fileList
    setFileList(_fileList)
  }

  // 3. 修改上传图片最大数量
  const changeMaxCount = (e) => {
    // 说明❓：setMacCount修改变量表现为异步（批处理）
    setMacCount(e.target.value)
    // console.log('切换：', maxCount, e.target.value, backupFileList.current)
    /**
     * 切换已上传图片列表:
     * 1. 切换单图：没有图片=>[] | 已经上传了图片=> [{url}] 只显示一张
     * 2. 切换三图：使用备份数据覆盖
     */
    if (e.target.value === 1) {
      const bk = backupFileList.current[0]
      setFileList(!!bk ? [bk] : [])
    }
    if (e.target.value === 3) {
      setFileList(backupFileList.current)
    }
  }
  // 4. 发布文章
  /**
   *
   * @param {*} formData 表单数据
   * @param {*} isDraft 是否为草稿
   * @returns
   */
  const publisArticle = async (formData, isDraft) => {
    const { type, ...sxd } = formData
    // 1. 判断选择的type(上传图片数量)和fileList(已上传图片)相等
    if (type !== fileList.length) {
      return message.warning('选择上传图片的数量不够！')
    }
    // 2. 组装后台发布文章需要的参数
    const data = {
      ...sxd,
      cover: {
        type,
        images: fileList.map((item) => item.url),
      },
    }
    // 如果是编辑，就将 id 存储到 data 中，传递给接口
    if (isEdit) {
      data.id = articleId
    }
    console.log('发布文章参数：', data)
    try {
      // 3. 发请求=》发布文章
      await dispatch(publishArticleAction(data, isDraft, isEdit))
      const text = isEdit ? '修改' : '发布'
      message.success(`${text}${isDraft ? '草稿' : '正式'}文章成功！`)
      nav('/article')
    } catch (error) {
      console.log(error)
    }
  }
  /**
   * 发布正式文章
   * @param {*} formData 表单变量数据
   */
  const onFinish = async (formData) => {
    console.log('表单变量数据:', formData)
    publisArticle(formData, false)
  }

  // 5. 发布草稿
  const saveDraft = async () => {
    try {
      const formData = await form.validateFields()
      // 表单校验通过
      console.log('校验成功：', formData)
      publisArticle(formData, true)
    } catch (error) {
      // 表单校验失败
      console.log('校验失败：', error)
    }
  }

  // 6. 编辑文章
  // 回填数据
  useEffect(() => {
    // 不是编辑状态直接return，不进行数据回填
    if (!isEdit) return
    ;(async () => {
      try {
        // 1. 获取回填数据
        const { data } = await getArticleApi(articleId)
        console.log('回填数据：', data)
        // 2. 进行回填
        const {
          title,
          content,
          channel_id,
          cover: { type, images },
        } = data.data
        // 通过form实例提供的setFieldsValue(表单数据formData),回填表单
        // 3. 准备表单回填需要的数据fromData
        const formData = { title, content, channel_id, type }
        form.setFieldsValue(formData)
        // 4. 回填之前上传过的图片
        // 格式：存储上传图片：[{url:''}...]
        const imgList = images.map((item) => ({ url: item }))
        // 回显上传过的图片
        setFileList(imgList)
        // 备份
        backupFileList.current = imgList
        // 设置最大上传数量
        setMacCount(type)
      } catch (error) {
        console.log(error)
      }
    })()
  }, [articleId, isEdit, form])

  useEffect(() => {
    console.log('参数变了：', params, form.getFieldValue('title'))
    if (!params['*'] && form.getFieldValue('title')) {
      form.resetFields()
      setFileList([])
    }
  }, [params, form])

  return (
    <div className={styles.root}>
      <Card
        title={
          <Breadcrumb separator=">">
            <Breadcrumb.Item>
              <Link to="/home">首页</Link>
            </Breadcrumb.Item>
            <Breadcrumb.Item>
              {isEdit ? '修改文章' : '发布文章'}
            </Breadcrumb.Item>
          </Breadcrumb>
        }
      >
        <Form form={form} initialValues={{ type: 1 }} onFinish={onFinish}>
          {/* 1. 文章标题 */}
          <Form.Item
            label="标题"
            name="title"
            rules={[{ required: true, message: '请输入文章标题' }]}
          >
            <Input placeholder="请输入文章标题" style={{ width: 400 }} />
          </Form.Item>
          {/* 2. 文章频道 */}
          <Form.Item
            label="频道"
            name="channel_id"
            rules={[{ required: true, message: '请选择文章频道' }]}
          >
            <Channel />
          </Form.Item>
          {/* 3. 文章的封面图片列表 */}
          <Form.Item label="封面">
            <Form.Item name="type">
              <Radio.Group onChange={changeMaxCount}>
                <Radio value={1}>单图</Radio>
                <Radio value={3}>三图</Radio>
                <Radio value={0}>无图</Radio>
                {/* <Radio value={-1}>自动</Radio> */}
              </Radio.Group>
            </Form.Item>
            {/* 上传组件
            maxCount > 0 才会渲染上传组件
             */}
            {maxCount > 0 && (
              <Upload
                className="avatar-uploader"
                // 接口地址
                // == 注意：Upload 再上传图片时，默认不会执行 axios 的请求，所以，此处需要手动设置完整接口地址
                action="http://geek.itheima.net/v1_0/upload"
                // == 发到后台的文件参数名（body）
                // 必须指定，根据接口文档的说明，需要设置为 image
                name="image"
                // 上传组件展示方式
                listType="picture-card"
                // 展示已上传图片列表（预览）
                showUploadList
                // 控制最大上传数量
                maxCount={maxCount}
                // 多选
                multiple={maxCount > 1}
                // 已经上传的文件列表，设置该属性后组件变为 受控=> 自定义控制已上传图片列表的显示
                fileList={fileList}
                // 上传文件改变时的回调
                onChange={onUploadChange}
              >
                <div style={{ marginTop: 8 }}>
                  <PlusOutlined />
                </div>
              </Upload>
            )}
          </Form.Item>
          {/* 4. 文章内容 */}
          <Form.Item
            label="内容"
            name="content"
            rules={[{ required: true, message: '请输入文章内容' }]}
          >
            {/* 富文本编辑器 */}
            <ReactQuill className="publish-quill" />
          </Form.Item>
          {/* 表单提交按钮 */}
          <Form.Item wrapperCol={{ offset: 4 }}>
            <Space>
              {/* 提交按钮 */}
              <Button size="large" type="primary" htmlType="submit">
                {isEdit ? '修改文章' : '发布文章'}
              </Button>
              {/* 普通按钮 */}
              <Button onClick={saveDraft} size="large">
                存入草稿
              </Button>
            </Space>
          </Form.Item>
        </Form>
      </Card>
    </div>
  )
}

export default Publish
